package com.keyleaf.up.document.service.impl;


import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.BooleanUtil;
import com.keyleaf.up.document.enums.PathType;
import com.keyleaf.up.document.DocumentClient;
import com.keyleaf.up.document.model.bo.FileInfoBO;
import com.keyleaf.up.document.model.dto.FileMergeAndDownloadDTO;
import com.keyleaf.up.document.model.dto.FileMergeDTO;
import com.keyleaf.up.document.service.IDocumentService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.util.UriUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author keyleaf
 * @since 2025/5/30
 **/
@Service
@Slf4j
@RequiredArgsConstructor
public class DocumentServiceImpl implements IDocumentService {

    private final DocumentClient documentClient;

    private static final String MERGED_PDF_NAME = "mergedPdf.pdf";

    @Override
    public String merge(FileMergeDTO fileMergeDTO) {
        List<File> files = fileMergeDTO.getFileInfos().stream().map(this::fetchFile).collect(Collectors.toList());
        try (InputStream inputStream = documentClient.mergeIntoPdf(files)) {
            File file = FileUtil.writeFromStream(inputStream, FileUtil.file(MERGED_PDF_NAME));
            return file.getPath();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public ResponseEntity<InputStreamResource> mergeAndDownload(FileMergeAndDownloadDTO fileMergeAndDownloadDTO) {
        ResponseEntity.BodyBuilder bodyBuilder = ResponseEntity.ok();
        List<File> files = fileMergeAndDownloadDTO.getFileInfos().stream().map(this::fetchFile).collect(Collectors.toList());
        try {
            InputStream inputStream = documentClient.mergeIntoPdf(files);
            HttpHeaders headers = new HttpHeaders();
            String fileName = UriUtils.encode(MERGED_PDF_NAME, StandardCharsets.UTF_8);
            if (BooleanUtil.isTrue(fileMergeAndDownloadDTO.getPreviewFlag())) {
                headers.add("Content-Disposition", "inline;filename=" + fileName);
            } else {
                headers.add("Content-Disposition", "attachment;filename=" + fileName);
            }
            headers.set(HttpHeaders.CONTENT_TYPE, "application/pdf;charset=UTF-8");
            headers.setAccessControlExposeHeaders(Collections.singletonList("*"));
            bodyBuilder.headers(headers);
            return new ResponseEntity<>(new InputStreamResource(inputStream), headers, HttpStatus.OK);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取文件
     *
     * @param fileInfo 文件信息
     * @return 本地文件
     */
    private File fetchFile(FileInfoBO fileInfo) {
        PathType pathType = fileInfo.getPathType();
        if (pathType == null) {
            throw new IllegalArgumentException("pathType cannot be null");
        }
        File file;
        switch (pathType) {
            case LOCAL:
                file = FileUtil.file(fileInfo.getPath());
                break;
            case HTTP:
            case OSS_MINIO:
            case OSS_ALI:
            default:
                throw new IllegalArgumentException("unsupported pathType: " + pathType.getCode());
        }
        return file;
    }

}
